package com.quectel.taskserver.job.event;

import cn.hutool.core.util.URLUtil;
import com.google.common.base.Preconditions;
import com.quectel.business.dms.application.ApplicationAccessConf;
import com.quectel.constant.core.device.DeviceTypeCodeConstants;
import com.quectel.core.module.application.dto.ApplicationDto;
import com.quectel.core.module.application.service.ApplicationService;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.entranceguard.service.EntranceGuardPersonService;
import com.quectel.core.module.household.dto.HouseholdDto;
import com.quectel.core.module.household.service.HouseholdService;
import com.quectel.sdk.hik8700.Hik8700ClientBuilder;
import com.quectel.sdk.hik8700.entranceguard.EntranceGuardClient;
import com.quectel.sdk.hik8700.entranceguard.model.SyncPersonResp;
import com.quectel.util.common.MyFileUtils;
import com.quectel.util.kit.StorageKit;
import com.quectel.util.redis.RedisUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 海康8700住户信息刷新任务
 *
 * @author: rananxin
 * @email: ryan.ran@quectel.com
 * @date: 2022-11-09 16:16:00
 */
@Component
public class Hik8700PersonFetchTask implements DataflowJob<ApplicationDto> {

    @DubboReference
    private ApplicationService applicationService;
    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private EntranceGuardPersonService entranceGuardPersonService;
    @DubboReference
    private HouseholdService householdService;

    private static final Logger LOGGER = LoggerFactory.getLogger(Hik8700PersonFetchTask.class);

    private static final String HIK_8700_FETCH_PERSON_EXEC_LIMIT = "HIK_8700_fetch_person_exec_limit:";

    @Override
    public List<ApplicationDto> fetchData(ShardingContext shardingContext) {
        List<ApplicationDto> applicationDtos = applicationService
                .fetchByConfCode(ApplicationAccessConf.ConfCodeEnum.HIK8700.getCode()
                        , shardingContext.getShardingTotalCount()
                        , shardingContext.getShardingItem());
        return applicationDtos.stream().filter(o -> DeviceTypeCodeConstants.HIK_8700_ENTRANCE_GUARD.equals(o.getDeviceType().getCode())).collect(Collectors.toList());

    }

    @Override
    public void processData(ShardingContext shardingContext, List<ApplicationDto> list) {
        boolean setnx = RedisUtils.setnx(HIK_8700_FETCH_PERSON_EXEC_LIMIT + shardingContext.getShardingItem(), "", 30, TimeUnit.MINUTES);
        if (setnx) {
            try {
                for (ApplicationDto application : list) {
                    try {
                        ApplicationAccessConf.TemplateOfHik8700Conf templateOfHik8700Conf = ApplicationAccessConf
                                .parseExtStr(ApplicationAccessConf.TemplateOfHik8700Conf.class, application.getAccessConf());

                        assert templateOfHik8700Conf != null;
                        EntranceGuardClient build = Hik8700ClientBuilder.builder()
                                .key(templateOfHik8700Conf.getKey())
                                .secret(templateOfHik8700Conf.getSecret())
                                .host(templateOfHik8700Conf.getHost())
                                .build(EntranceGuardClient.class);

                        build.drawPersons(rs -> personInfoHandle(application, rs));
                    } catch (Exception e) {
                        LOGGER.error("hik8700查询人员信息异常", e);
                    }
                }
            } finally {
                RedisUtils.del(HIK_8700_FETCH_PERSON_EXEC_LIMIT + shardingContext.getShardingItem());
            }
        }
    }

    private void personInfoHandle(ApplicationDto application, List<SyncPersonResp> personResps) {
        if (CollectionUtils.isEmpty(personResps)) {
            return;
        }

        ApplicationAccessConf.TemplateOfHik8700Conf templateOfHik8700Conf = ApplicationAccessConf
                .parseExtStr(ApplicationAccessConf.TemplateOfHik8700Conf.class, application.getAccessConf());

        for (SyncPersonResp personResp : personResps) {
            try {
                if (StringUtils.isBlank(personResp.getPhoto())
                        || !personResp.getPhoto().contains("photo")) {
                    continue;
                }
                Preconditions.checkNotNull(templateOfHik8700Conf);
                List<HouseholdDto> householdDtos = householdService.selectByMobile(personResp.getPhoneNo());
                if (CollectionUtils.isNotEmpty(householdDtos)) {

                    for (HouseholdDto householdDto : householdDtos) {
                        if (StringUtils.isBlank(householdDto.getFaceImg())) {
                            String actualUrl = personResp.getPhoto().replace("null", "http://" + templateOfHik8700Conf.getHost());

                            File faceImgFile = MyFileUtils.downloadToTempDir(URLUtil.encode(actualUrl), false);
                            String url = StorageKit.uploadToPublicBucketObtainUrl(faceImgFile);

                            HouseholdDto newlyDto = new HouseholdDto();
                            newlyDto.setId(householdDto.getId());
                            newlyDto.setFaceImg(url);
                            householdService.updateById(newlyDto);
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.error("海康8700 人员同步处理异常", e);
            }
        }
    }
}
